﻿using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Media;

namespace MyUtils.PInvoke
{
	public static class GlassWindowWpf
	{
		[Obsolete("Use Glass", true)]
		public static bool MakeGlassWindow(this Window wpfWindow)
		{
			return MakeGlassWindow(wpfWindow, wpfWindow.Background);
		}

		[Obsolete("Use Glass", true)]
		public static bool MakeGlassWindow(this Window wpfWindow, Brush defaultBackground)
		{
			return Glass(wpfWindow, defaultBackground);
		}

		public static bool Glass(this Window wpfWindow, bool enabled = true, bool mouseDownOnTitle = true)
		{
			return Glass(wpfWindow, wpfWindow.Background, enabled, mouseDownOnTitle);
		}

		public static bool Glass(this Window wpfWindow, Brush defaultBackground, bool enabled = true, bool mouseDownOnTitle = true)
		{
			if (wpfWindow == null)
			{
				throw new ArgumentNullException("wpfWindow");
			}
			if (PInvoke.GlassEnabled)
			{
				//if(wpfWindow.IsHandleCreated
				var mainWindowSrc = HwndSource.FromHwnd(new WindowInteropHelper(wpfWindow).Handle);
				if (mainWindowSrc != null)
				{
					if (mainWindowSrc.CompositionTarget != null)
					{
						mainWindowSrc.CompositionTarget.BackgroundColor = Colors.Transparent;
					}
					GlassWindow.Extend(mainWindowSrc.Handle, enabled);

					if(GetGlassOriginalBackground(wpfWindow) == null)
					{
						SetGlassOriginalBackground(wpfWindow, wpfWindow.Background);
					}

					wpfWindow.Background = enabled ? Brushes.Transparent : GetGlassOriginalBackground(wpfWindow);
					wpfWindow.MouseDown -= WpfWindowMouseDown;
					wpfWindow.MouseDown -= WpfWindowMouseDown;
					if(mouseDownOnTitle && enabled)
					{
						wpfWindow.MouseDown += WpfWindowMouseDown;
					}
					return true;
				}
			}

			wpfWindow.Background = defaultBackground;
			return false;
		}

		static void WpfWindowMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
		{
			SimulateMouseDownOnTitleBar((Window) sender);
		}

		public static void SimulateMouseDownOnTitleBar(this Window wpfWindow)
		{
			PInvoke.ReleaseCapture();
			PInvoke.SendMessage(new WindowInteropHelper(wpfWindow).Handle, PInvoke.WM_NCLBUTTONDOWN, PInvoke.HT_CAPTION, 0);
		}

		public static DependencyProperty EnableGlassProperty = DependencyProperty.RegisterAttached("EnableGlass",
																								   typeof(bool),
																								   typeof(Window), new PropertyMetadata(false, EnableGlassChanged));

		static DependencyPropertyKey GlassOriginalBackgroundProperty = DependencyProperty.RegisterAttachedReadOnly("GlassOriginalBackground",
																								   typeof(Brush),
																								   typeof(Window), new PropertyMetadata());

		private static void EnableGlassChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
		{
			if ((bool) e.OldValue != (bool) e.NewValue && !DesignerProperties.GetIsInDesignMode(d))
			{

				if ((bool) e.NewValue)
				{
					if (!((Window)d).IsLoaded)
					{
						((Window)d).Loaded -= GlassWindowLoaded;
						((Window)d).Loaded += GlassWindowLoaded;
					}
					else
					{
						((Window)d).Glass();
					}
				}
				else
				{
					((Window) d).Glass(false);
				}
			}
		}

		static void GlassWindowLoaded(object sender, RoutedEventArgs e)
		{
			((Window)sender).Loaded -= GlassWindowLoaded;
			((Window)sender).Glass();
		}

		public static bool GetEnableGlass(Window window)
		{
			return (bool)window.GetValue(EnableGlassProperty);
		}

		public static void SetEnableGlass(Window window, bool value)
		{
			window.SetValue(EnableGlassProperty, value);
		}

		static Brush GetGlassOriginalBackground(Window window)
		{
			return (Brush)window.GetValue(GlassOriginalBackgroundProperty.DependencyProperty);
		}

		static void SetGlassOriginalBackground(Window window, Brush value)
		{
			window.SetValue(GlassOriginalBackgroundProperty, value);
		}
	}
}
